package com.xuerhua.yxt.excel.tags;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.util.CellRangeAddress;

import com.xuerhua.yxt.excel.ExcelParser;
import com.xuerhua.yxt.excel.WorkbookUtils;


/**
 * <b>IfTag</b> is a class which parse #if #end
 */
public class IfTag implements ITag {
    public static final String KEY_IF = "#if";

    public static final String KEY_END = "#end";

    public int[] parseTag(HSSFSheet sheet, HSSFRow curRow, HSSFCell curCell) {
        int ifstart = curRow.getRowNum();
        int ifend = -1;
        int ifCount = 0;
        String ifstr = "";
        boolean bFind = false;
        for (int rownum = ifstart; rownum <= sheet.getLastRowNum(); rownum++) {
            HSSFRow row = sheet.getRow(rownum);
            if (null == row)
                continue;
            for (int colnum = row.getFirstCellNum(); colnum <= row.getLastCellNum(); colnum++) {
                HSSFCell cell = row.getCell(colnum);
                if (null == cell)
                    continue;
                if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                    String cellstr = cell.getRichStringCellValue().getString();

                    // get the tag instance for the cellstr
                    ITag tag = ExcelParser.getTagClass(cellstr);

                    if (null != tag) {
                        if (tag.hasEndTag()) {
                            if (0 == ifCount) {
                                ifstart = rownum;
                                ifstr = cellstr;
                            }
                            ifCount++;
                            break;
                        }
                    }
                    if (cellstr.startsWith(KEY_END)) {
                        ifend = rownum;
                        ifCount--;
                        if (ifstart >= 0 && ifend >= 0 && ifend > ifstart && ifCount == 0) {
                            bFind = true;
                        }
                        break;
                    }
                }
            }
            if (bFind)
                break;
        }

        if (!bFind)
            return new int[] { 0, 0, 1 };

        // test if condition
        boolean bResult = false;
        // remove #if tag and get condition expression
        String expr = ifstr.trim().substring(KEY_IF.length()).trim();

        // parse the condition expression
        try {
            bResult = (Boolean)ExcelParser.parseExpr(expr);
        }
        catch (Exception e) {//
        }

        if (bResult) { // if condition is true
            // remove #if tag and #end tag only
            sheet.removeRow(WorkbookUtils.getRow(ifstart, sheet));
            sheet.removeRow(WorkbookUtils.getRow(ifend, sheet));
            // remove merged region in ifstart & ifend
            for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
                CellRangeAddress r = sheet.getMergedRegion(i) ;
                if (r.getFirstRow() == ifstart && r.getLastRow() == ifstart || r.getFirstRow() == ifend
                        && r.getLastRow() == ifend) {
                    sheet.removeMergedRegion(i);
                    // we have to back up now since we removed one
                    i = i - 1;
                }
            }
            if (sheet.getLastRowNum() > ifend) {
                sheet.shiftRows(ifend + 1, sheet.getLastRowNum(), -1, true, true);
            }
            sheet.shiftRows(ifstart + 1, sheet.getLastRowNum(), -1, true, true);
            return new int[] { 1, -2, 1 };
        }
        else { // if condition is false
               // remove #if #end block
            for (int rownum = ifstart; rownum <= ifend; rownum++) {
                sheet.removeRow(WorkbookUtils.getRow(rownum, sheet));
            }
            // remove merged region in ifstart & ifend
            for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
                CellRangeAddress r = sheet.getMergedRegion(i);
                if (r.getFirstRow() >= ifstart && r.getLastRow() <= ifend) {
                    sheet.removeMergedRegion(i);
                    // we have to back up now since we removed one
                    i = i - 1;
                }
            }
            sheet.shiftRows(ifend + 1, sheet.getLastRowNum(), -(ifend - ifstart + 1), true, true);
            return new int[] { ExcelParser.getSkipNum(ifstart, ifend), ExcelParser.getShiftNum(ifend, ifstart), 1 };
        }
    }

    public String getTagName() {
        return KEY_IF;
    }

    public boolean hasEndTag() {
        return true;
    }
}
